package tt.dz.egobus.servicemanager.service.impl;

import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tt.dz.egobus.api.ResponseBack;
import tt.dz.egobus.api.exception.ResponseException;
import tt.dz.egobus.api.managerservice.manager.*;
import tt.dz.egobus.api.usercenter.user.UserInfoBack;
import tt.dz.egobus.bean.ServiceManagerI18NCodeEnum;
import tt.dz.egobus.cache.service.ExtendCacheService;
import tt.dz.egobus.servicemanager.base.service.AbstractFacadeServiceConfig;
import tt.dz.egobus.servicemanager.bean.SpringConfigConstant;
import tt.dz.egobus.servicemanager.business.distance.MaxOverAlgorithm;
import tt.dz.egobus.servicemanager.business.distance.SPIMaxOverAlgorithmFactory;
import tt.dz.egobus.servicemanager.business.key.DriverStatus;
import tt.dz.egobus.servicemanager.business.point.AddressPoint;
import tt.dz.egobus.servicemanager.business.point.BusPoint;
import tt.dz.egobus.servicemanager.business.point.CommonPoint;
import tt.dz.egobus.servicemanager.business.point.Point;
import tt.dz.egobus.servicemanager.core.factory.IdFactory;
import tt.dz.egobus.servicemanager.entities.*;
import tt.dz.egobus.servicemanager.facade.interator.FacadeFactory;
import tt.dz.egobus.servicemanager.facade.interator.FacadeFactoryLoggerInterceptorHolder;
import tt.dz.egobus.servicemanager.facade.user.UserCenterFacade;
import tt.dz.egobus.servicemanager.service.*;
import tt.dz.egobus.servicemanager.service.BusService;
import tt.dz.egobus.servicemanager.util.PojoConvertVoUtils;
import tt.dz.egobus.servicemanager.vo.BusinessFinishVo;
import tt.dz.egobus.servicemanager.vo.BusinessRequestVo;
import tt.dz.egobus.vo.KV;

import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.List;

import static org.apache.commons.lang3.StringUtils.defaultString;
import static tt.dz.egobus.bean.I18NCodeEnum.*;
import static tt.dz.egobus.bean.ServiceManagerI18NCodeEnum.*;

/**
 * @author Anson
 * @date 17-3-21
 * @name 管理服务
 * @since 1.0.2
 */
@Service("managerServiceImpl")
@Transactional
public class ManagerServiceImpl extends AbstractFacadeServiceConfig implements ManagerService {
    static final Logger LOGGER = LoggerFactory.getLogger(ManagerServiceImpl.class);

    @Autowired
    @Qualifier("busServiceImpl")
    BusService busService;

    @Autowired
    @Qualifier("busServiceServiceImpl")
    BusServiceService busServiceService;

    @Autowired
    @Qualifier("driverRegisterBusRelativeServiceImpl")
    DriverRegisterBusRelativeService driverRegisterBusRelativeService;

    @Autowired
    @Qualifier("businessServiceServiceImpl")
    BusinessServiceService businessServiceService;

    @Autowired
    @Qualifier("businessServiceInfoServiceImpl")
    BusinessServiceInfoService businessServiceInfoService;

    @Autowired
    @Qualifier("busRegisterServiceServiceImpl")
    BusRegisterServiceService busRegisterServiceService;

    @Autowired
    @Qualifier("businessExceptionAlertServiceImpl")
    BusinessExceptionAlertService alertService;

    @Autowired
    @Qualifier("redisBusinessWorkCacheServiceImpl")
    BusinessWorkCacheService businessWorkCacheService;

    @Autowired
    @Qualifier("redisBusinessCacheServiceImpl")
    BusinessCacheService businessCacheService;

    @Autowired
    @Qualifier("springConfigConstant")
    SpringConfigConstant springConfigConstant;

    @Autowired
    @Qualifier("extendsRedisServiceImpl")
    ExtendCacheService extendCacheService;

    /**
     * 业务服务号可容纳的最大服务距离计算算法
     */
    IdFactory<MaxOverAlgorithm> maxOverAlgorithmIdFactory = new SPIMaxOverAlgorithmFactory();

    @Override
    @PostConstruct
    public FacadeFactory getFacadeFactory() {
        return FacadeFactoryLoggerInterceptorHolder.LOGGER_FACADE;
    }

    @Override
    @Transactional
    public ResponseBack<Boolean> active(String busId, String driverId) {
        try {
            //不存在有效的车服务，即车没有注册有效的服务
            int[] businessCodes = this.busRegisterServiceService.queryBusinessCodeByBusId(busId);
            if (ArrayUtils.isEmpty(businessCodes)) {
                throw new ResponseException(RPC_BUS_UN_BIND_SERVICE_ERROR);
            }
            DriverStatus status = businessWorkCacheService.getStatus(driverId);
            LOGGER.info("司机上线触发->当前获取司机状态={}", status);
            //$$校验当前司机端的状态是否一致
            if (status != null && !DriverRegisterBusRelative.RelativeStatus.assertUnActive(status.getStatus())) {
                throw new ResponseException(RPC_DRIVER_CAN_NOT_ACTIVE_ERROR);
            }
            UserInfoBack driverInfo = validateAndGetUserInfo(driverId);
            Bus bus = validateBus(busId);
            if (!bus.assertNotUsed()) {
                //当前车的类型没有处于未使用的状态
                throw new ResponseException(RPC_BUS_CAN_NOT_ACTIVE_ERROR);
            }
            //车是否存在绑定关系
            boolean isBindedCar = driverRegisterBusRelativeService.isValidateBindCar(busId);
            //司机是否已经存在绑定关系
            boolean isBindedDriverCar = driverRegisterBusRelativeService.isValidateBindDriver(driverId);
            //检查当前是否存在已经绑定的关系
            if (isBindedCar || isBindedDriverCar) {
                //进入当前条件下,只有两种:车已经被用了,司机已经被绑定了关系
                ServiceManagerI18NCodeEnum i18NCodeEnum = isBindedCar ? RPC_BUS_CAN_NOT_ACTIVE_ERROR :
                        RPC_DRIVER_CAN_NOT_ACTIVE_ERROR;
                throw new ResponseException(i18NCodeEnum);
            }
            //bus的状态在数据库要同步为在使用中
            boolean isActive = this.driverRegisterBusRelativeService.active(busId, driverInfo);
            if (isActive) {
                businessWorkCacheService.active(driverId, businessCodes);
            }
            return ResponseBack.success(isActive);
        } catch (ResponseException e) {
            return ResponseBack.error(e);
        }
    }


    @Override
    @Transactional
    public ResponseBack<Boolean> down(String driverId) {
        KV<Integer, DriverRegisterBusRelative> relativeKV = this.getValidateDriverRegisterBusRelative(driverId, this
                .driverRegisterBusRelativeService);
        DriverRegisterBusRelative relative = relativeKV.getV();
        if (!relative.isAbleDown()) {
            throw new ResponseException(RPC_DRIVER_IN_BUSINESS_ERROR);
        }
        boolean isDown = this.driverRegisterBusRelativeService.down(relative);
        if (isDown) {
            businessWorkCacheService.down(driverId);
        }
        return ResponseBack.success(isDown);
    }

    @Override
    @Transactional
    public ResponseBack<Boolean> doBeginBusiness(String driverId, String businessId, String userId, BusPoint
            busPoint, BusinessRequestVo businessRequestVo) {
        KV<Integer, DriverRegisterBusRelative> relativeKV = this.getValidateDriverRegisterBusRelative(driverId, this
                .driverRegisterBusRelativeService);
        DriverRegisterBusRelative relative = relativeKV.getV();
        if (!relative.isAbleDoBeginBusiness()) {
            //异常的司机绑定状态
            LOGGER.error("开始业务->校验关系异常isAbleDoBeginBusiness=false");
            throw new ResponseException(RPC_DRIVER_NOT_IN_BEGIN_BUSINESS_ERROR);
        }
        //更新当前司机的状态
        boolean isDone = businessWorkCacheService.doDriverBeginBusiness(driverId);
        LOGGER.info("调用者确认某个司机进行派单分发->更新当前司机的状态为={}", isDone);
        if (isDone) {
            //更新当前司机绑定车辆状态
            isDone = this.driverRegisterBusRelativeService.doUpdateBeginBusiness(relative, businessId);
            LOGGER.info("开始业务->当前更新当前司机绑定车辆状态={}", isDone);
            if (!isDone) {
                //事务回滚
                throw new ResponseException(RPC_CREATE_BUSINESS_SERVICE_ERROR);
            }
            //创建一个业务流水号
            isDone = this.businessServiceService.doSaveBeginBusiness(relative, businessId, userId, busPoint,
                    businessRequestVo);
            if (!isDone) {
                //事务回滚
                throw new ResponseException(RPC_SYSTEM_CODE_ERROR);
            }
            //若是当前的处理结果成功，则确认当前分配的结果正确性
            //则在缓存业务中需要删除当前对应的缓存
            LOGGER.info("调用者确认某个司机进行派单分发->删除业务队列缓存={}", businessId);
            businessCacheService.deleteBusiness(businessId);
        }


        return ResponseBack.success(isDone);
    }

    @Override
    @Transactional
    public ResponseBack<Boolean> doBusiness(String driverId, BusinessService businessService, AddressPoint
            addressPoint) {
        if (businessService == null || addressPoint == null) {
            return ResponseBack.success(false);
        }
        String businessId = businessService.getBusinessId();
        String relativeId = businessService.getServiceRegisterId();
        //更新当前司机绑定车辆状态
        boolean isDone = driverRegisterBusRelativeService.doBusiness(relativeId);
        if (isDone) {
            //更新当前绑定服务的状态
            isDone = this.businessServiceService.doSaveBusiness(businessId, addressPoint);
            if (!isDone) {
                //事务回滚
                throw new ResponseException(RPC_SYSTEM_CODE_ERROR);
            }
            //更新当前司机的状态
            isDone = businessWorkCacheService.doTask(driverId);
            LOGGER.info("司机确认身份之后->更新当前司机的状态为={}", isDone);
            if (!isDone) {
                //事务回滚
                throw new ResponseException(RPC_SYSTEM_CODE_ERROR);
            }
        }
        return ResponseBack.success(isDone);
    }

    @Override
    @Transactional
    public ResponseBack<TaskInfo> getTaskInfo(String businessId) {
        if (StringUtils.isEmpty(businessId)) {
            throw new ResponseException(RPC_PARAM_ILLEGAL_ERROR);
        }
        BusinessService businessService = businessServiceService.getBusinessByBusinessId(businessId);
        if (null == businessService) {
            throw new ResponseException(RPC_PARAM_ENTITY_ERROR);
        }
        BusinessServiceInfo businessServiceInfo = businessServiceInfoService.getInfoByServiceId(businessService.getId
                ());
        if (null == businessServiceInfo) {
            throw new ResponseException(RPC_PARAM_ENTITY_ERROR);
        }
        TaskInfo taskInfo = PojoConvertVoUtils.businessDetailConvertTaskInfo(businessService, businessServiceInfo);
        return ResponseBack.success(taskInfo);
    }

    @Override
    @Transactional
    public ResponseBack<BusinessServiceInfo> doFinish(BusinessFinishVo vo) {
        if (vo == null || !vo.validate()) {
            throw new ResponseException(RPC_PARAM_ILLEGAL_ERROR);
        }
        String driverId = vo.getDriverId();
        String businessId = vo.getBusinessId();

        KV<Integer, DriverRegisterBusRelative> relativeKV = this.getValidateDriverRegisterBusRelative(driverId, this
                .driverRegisterBusRelativeService);
        DriverRegisterBusRelative relative = relativeKV.getV();
        double distance = businessWorkCacheService.validateDistance(vo);
        LOGGER.info("司机接单完成时候->获取处理当前里程数，businessId={},distance={}", businessId, distance);
        vo.setRealDistance(distance);
        BusinessService businessService = businessServiceService.getBusinessByBusinessId(businessId);
        //处理当前司机与车辆之间的状态 business --> active
        boolean isDone = driverRegisterBusRelativeService.doFinish(relative, vo);
        if (isDone) {
            //处理当前业务状态 business -> finish
            //更新当前绑定服务的状态
            isDone = this.businessServiceService.doSaveFinish(businessService, vo);
            if (!isDone) {
                //事务回滚
                LOGGER.error("司机接单完成时候->数据库操作异常，businessId={}", businessId);
                throw new ResponseException(RPC_SYSTEM_CODE_ERROR);
            }
            isDone = businessWorkCacheService.doFinish(vo);
            if (!isDone) {
                //事务回滚
                LOGGER.error("司机接单完成时候->更新司机的状态缓存异常，businessId={}", businessId);
                throw new ResponseException(RPC_DRIVER_INVALIDATE_STATUS_ERROR);
            }
        }
        BusinessServiceInfo businessServiceInfo = businessServiceInfoService.getInfoByServiceId(businessService.getId
                ());
        return ResponseBack.success(businessServiceInfo);
    }

    @Override
    @Transactional
    public ResponseBack<Boolean> doUserCancel(String userId, String businessId) {
        if (StringUtils.isEmpty(userId) || StringUtils.isEmpty(businessId)) {
            throw new ResponseException(RPC_PARAM_ILLEGAL_ERROR);
        }
        BusinessService businessService = businessServiceService.getBusinessByBusinessId(businessId);
        if (businessService == null) {
            throw new ResponseException(RPC_PARAM_ENTITY_ERROR);
        }
        boolean isDone = businessService.assertBeginBusiness();
        if (!isDone) {
            //当前状态不是业务开始的状态的时候
            LOGGER.error("用户取消触发->当前派单信息的获取是否可以确认DoBusiness状态={},业务信息={}", isDone, businessId);
            return ResponseBack.success(isDone);
        }
        String driverId = businessService.getDriverId();
        isDone = driverRegisterBusRelativeService.doUserCancel(businessService.getDriverRegisterBusRelative());
        if (!isDone) {
            //当前状态不是业务开始的状态的时候
            LOGGER.error("用户取消触发->司机状态取消同步是否可以确认DoBusiness状态={},业务信息={}", isDone, businessId);
            return ResponseBack.success(isDone);
        }
        LOGGER.info("用户取消触发->当前派单信息的获取司机={},业务信息={}", driverId, businessId);
        isDone = businessServiceService.doSaveUserCancel(businessService);
        if (!isDone) {
            return ResponseBack.success(isDone);
        }
        //只要司机不处于business状态的时候可以退单
        isDone = businessWorkCacheService.doUserCancel(driverId);
        LOGGER.info("用户取消触发->当前司机处于状态,是否成功={}", isDone);
        if (!isDone) {
            //事务回滚
            LOGGER.error("用户取消触发->当前司机状态修改异常,司机={},业务信息={}", driverId, businessId);
            throw new ResponseException(RPC_SYSTEM_CODE_ERROR);
        }
        return ResponseBack.success(isDone);
    }

    @Override
    @Transactional
    public ResponseBack<Boolean> modifyBusinessOrderStatus(String businessId, String orderId, int status) {
        if (StringUtils.isEmpty(orderId)) {
            throw new ResponseException(RPC_PARAM_ILLEGAL_ERROR);
        }
        LOGGER.info("修改业务订单状态->当前businessId={},orderId={}，status={}", businessId, orderId, status);
        BusinessService businessService = null;
        if (!StringUtils.isEmpty(businessId)) {
            businessService = businessServiceService.getBusinessByBusinessId(businessId);
        } else {
            businessService = businessServiceService.getBusinessByOrderId(orderId);
        }
        if (businessService == null) {
            throw new ResponseException(RPC_PARAM_ENTITY_ERROR);
        }
        boolean isDone = businessServiceService.modifyBusinessOrderStatus(businessService, orderId, status, null);
        return ResponseBack.success(isDone);
    }

    @Override
    @Transactional
    public ResponseBack<Boolean> doSaveBusinessExceptionAlert(ExceptionRequest alert) {
        String driverId = alert.getDriverId();
        UserCenterFacade facade = getUserFacade();
        ResponseBack<UserInfoBack> userInfoBackResponseBack = facade.findUserInfo(driverId);
        if ((!userInfoBackResponseBack.isSuccess()) || userInfoBackResponseBack.getResult() == null) {
            LOGGER.error("司机异常触发->当前司机不为空，司机用户未找到,当前司机={}", driverId);
            throw new ResponseException(RPC_USER_NOT_FOND);
        }
        UserInfoBack userInfoBack = userInfoBackResponseBack.getResult();
        LOGGER.info("司机异常触发->当前司机={}", driverId);
        DriverStatus status = businessWorkCacheService.getStatus(driverId);
        //当前司机若为空，则表示当前并没有激活，可以上报异常
        //当前司机不为空，而且处于业务中，则不能上报异常
        if (status != null && !DriverRegisterBusRelative.RelativeStatus.isAbleException(status.getStatus())) {
            LOGGER.error("司机异常触发->当前司机不为空，而且处于业务中，则不能上报异常,当前司机={}", driverId);
            throw new ResponseException(RPC_EXCEPTION_BUSINESS_NOT_FINISH);
        }
        KV<Integer, DriverRegisterBusRelative> relativeKV = this.getValidateDriverRegisterBusRelative(driverId, this
                .driverRegisterBusRelativeService);
        int count = relativeKV.getK();
        DriverRegisterBusRelative relative = relativeKV.getV();
        BusinessExceptionAlert pojo = PojoConvertVoUtils.exceptionRequestConvertExceptionAlert(alert);
        if (pojo.assertBus() && count == 0) {
            //未上线，但上报了车辆异常
            LOGGER.error("司机异常触发->当前司机并未上线,当前司机={}", driverId);
            throw new ResponseException(RPC_DRIVER_UNBIND_BUS_ERROR);
        }

        boolean isDone = true;
        if (count == 1) {
            if (!relative.isAbleException()) {
                //当前车辆与司机的关系处于业务中的关系，则不能上报异常
                LOGGER.error("司机异常触发->当前司机与车辆绑定状态处于业务中，不能上报异常,当前司机={},status={}", driverId, relative.getStatus());
                throw new ResponseException(RPC_DRIVER_INVALIDATE_STATUS_ERROR);
            }
            Bus bus = relative.getBus();
            if (pojo.assertBus() && bus != null) {
                pojo.setBusNo(bus.getCarNo());
            }
            //处理当前司机与车辆之间的状态  exception
            //并且处理车辆状态 unuse 或则是exeption
            isDone = driverRegisterBusRelativeService.doSaveException(relative, pojo);
        }
        pojo.setDriverMobile(userInfoBack.getPhoneNumber());
        pojo.setDriverName(userInfoBack.getRealName());
        if (!isDone) {
            return ResponseBack.success(isDone);
        }
        alertService.save(pojo);
        this.businessWorkCacheService.doException(driverId);
        return ResponseBack.success(isDone);
    }

    @Override
    public ResponseBack<Boolean> isOverMaxDistance(PointDistance pointDistance, int businessCode) {
        MaxOverAlgorithm maxOverAlgorithm = maxOverAlgorithmIdFactory.factory(String.valueOf(businessCode));
        if (maxOverAlgorithm == null) {
            return ResponseBack.success(false);
        }
        KV<Point, Point> kv = this.convert(pointDistance);
        boolean isOver = maxOverAlgorithm.isOverMaxDistance(kv.getK(), kv.getV());
        return ResponseBack.success(isOver);
    }

    @Override
    @Transactional
    public ResponseBack<List<BusinessCodeServiceStatus>> queryBusinessCodeServiceInfo() {
        List<tt.dz.egobus.servicemanager.entities.BusService> list = this.busServiceService.list(null);
        if (list == null) {
            return ResponseBack.success(new ArrayList<BusinessCodeServiceStatus>(0));
        }
        List<BusinessCodeServiceStatus> vos = new ArrayList<BusinessCodeServiceStatus>(list.size());
        BusinessCodeServiceStatus vo = null;
        for (tt.dz.egobus.servicemanager.entities.BusService o : list) {
            vos.add(PojoConvertVoUtils.busServiceConvertBusinessCodeServiceStatus(o));
        }
        return ResponseBack.success(vos);
    }

    @Override
    @Transactional
    public ResponseBack<Boolean> isBusinessCodeActive(int businessCode) {
        Boolean isActive = this.busServiceService.isBusinessCodeActive(businessCode);
        return ResponseBack.success(isActive);
    }

    @Override
    @Transactional
    public ResponseBack<Boolean> isExitUserUnDoneBusiness(String userId) {
        boolean isExits = this.businessServiceService.isExitUserUnDoneBusiness(userId);
        return ResponseBack.success(isExits);
    }

    @Override
    @Transactional
    public ResponseBack<TaskInfo> getUserUnDoneTaskInfo(String userId) {
        if (StringUtils.isEmpty(userId)) {
            throw new ResponseException(RPC_PARAM_ILLEGAL_ERROR);
        }
        BusinessService businessService = this.businessServiceService.getUserUnDoneService(userId);
        if (null == businessService) {
            return ResponseBack.success(null);
        }
        BusinessServiceInfo businessServiceInfo = this.businessServiceInfoService.getInfoByServiceId(businessService
                .getId());
        if (null == businessServiceInfo) {
            //从业务流程控制上,是不会进入当前这语法中
            return ResponseBack.success(null);
        }
        TaskInfo info = PojoConvertVoUtils.businessDetailConvertTaskInfo(businessService, businessServiceInfo);
        return ResponseBack.success(info);
    }

    @Override
    @Transactional
    public ResponseBack<TaskInfo> getDriverUnDoneTaskInfo(String driverId) {
        if (StringUtils.isEmpty(driverId)) {
            throw new ResponseException(RPC_PARAM_ILLEGAL_ERROR);
        }
        BusinessService businessService = this.businessServiceService.getDriverUnDoneService(driverId);
        if (null == businessService) {
            return ResponseBack.success(null);
        }
        BusinessServiceInfo businessServiceInfo = this.businessServiceInfoService.getInfoByServiceId(businessService
                .getId());
        if (null == businessServiceInfo) {
            //从业务流程控制上,是不会进入当前这语法中
            return ResponseBack.success(null);
        }
        TaskInfo info = PojoConvertVoUtils.businessDetailConvertTaskInfo(businessService, businessServiceInfo);
        return ResponseBack.success(info);
    }

    @Override
    @Transactional
    public ResponseBack<TaskInfo> getDriverLastestTaskInfo(String driverId) {
        if (StringUtils.isEmpty(driverId)) {
            throw new ResponseException(RPC_PARAM_ILLEGAL_ERROR);
        }
        BusinessServiceInfo businessServiceInfo = this.businessServiceInfoService.getDriverLastestTaskInfo(driverId);
        if (null == businessServiceInfo) {
            //从业务流程控制上,是不会进入当前这语法中
            return ResponseBack.success(null);
        }
        BusinessService businessService = businessServiceInfo.getBusinessService();
        TaskInfo info = PojoConvertVoUtils.businessDetailConvertTaskInfo(businessService, businessServiceInfo);
        return ResponseBack.success(info);
    }

    @Override
    @Transactional
    public ResponseBack<Integer> getDriverBusinesCount(String driverId) {
        if (StringUtils.isEmpty(driverId)) {
            throw new ResponseException(RPC_PARAM_ILLEGAL_ERROR);
        }
        Integer count = this.businessServiceService.getDriverBusinesCount(driverId);
        count = count == null ? 0 : count;
        return ResponseBack.success(count);
    }

    @Override
    @Transactional
    public ResponseBack<Integer[]> queryDriverBusinessCodeCount(Integer[] businessCodes, String driverId) {
        if (businessCodes == null || businessCodes.length == 0 || StringUtils.isEmpty(driverId)) {
            return ResponseBack.success(null);
        }
        Integer[] counts = this.businessServiceService.queryDriverBusinessCodeCount(businessCodes, driverId);
        return ResponseBack.success(counts);
    }

    @Override
    public ResponseBack<Integer> getSystemAllMaxDistanceLength() {
        return ResponseBack.success(springConfigConstant.getSingleMax());
    }

    @Transactional
    @Override
    public BusinessView getServiceViewByBusinessId(String businessId) {

        if (StringUtils.isBlank(businessId)) {
            return null;
        }
        BusinessServiceInfo info = this.businessServiceInfoService.getInfoByBusinessId(businessId);
        if (info == null) {
            return null;
        }
        //处理公共基础业务信息
        BusinessService businessService = info.getBusinessService();
        if (businessService == null) {
            return null;
        }

        BusinessView view = new BusinessView();

        String busId = info.getBusId();
        //封装车辆信息
        this.packageBusViewInfo(busId, view);
        PojoConvertVoUtils.convertBusinessInfoToView(info, view);
        return view;
    }


    /**
     * @param busId 当前车辆id
     * @param view  当前视图实体类
     * @author Anson
     * @date 17-5-16
     * @name 封装车辆信息
     * @since 1.0.4
     */
    void packageBusViewInfo(String busId, BusinessView view) {
        if (StringUtils.isBlank(busId) || view == null) {
            return;
        }
        Bus bus = this.busService.get(busId);
        if (bus == null) {
            return;
        }
        String busNo = defaultString(bus.getCarNo(), "");
        /**座位数*/
        int seatNum = 0;
        /**品牌信息 */
        String busBrand = "";
        /** 车辆型号*/
        String busVersion = "";
        BusType busType = bus.getBusType();
        if (busType != null) {
            seatNum = busType.getSeatNum();
            busBrand = busType.getBrand();
            busVersion = busType.getVersion();
        }
        view.setBusId(busId);
        view.setBusNo(busNo);
        view.setSeatNum(seatNum);
        view.setBusBrand(busBrand);
        view.setBusVersion(busVersion);
    }


    /**
     * @param busId 车id
     * @author Anson
     * @date 17-3-23
     * @name 获取并验证当前车
     * @since 1.0.2
     */
    Bus validateBus(String busId) {
        Bus bus = busService.get(busId);
        if (bus == null) {
            throw new ResponseException(RPC_PARAM_ENTITY_ERROR);
        }
        return bus;
    }


    /**
     * @param driverId 司机id
     * @author Anson
     * @date 17-8-16
     * @name 校验并获取当前司机有效单一绑定关系
     * @since 1.0.6
     */
    KV<Integer, DriverRegisterBusRelative> getValidateDriverRegisterBusRelative(String driverId,
                                                                                DriverRegisterBusRelativeService
                                                                                        driRegBusRelatService) {
        List<DriverRegisterBusRelative> relatives = driRegBusRelatService.queryValidateCarDriverBind(driverId);

        int count = relatives.size();
        if (count != 1) {
            //异常的司机绑定状态
            LOGGER.error("司机状态绑定车辆关系错误");
            ServiceManagerI18NCodeEnum i18NCodeEnum = count == 0 ? RPC_BUS_DRIVER_RELATIVE_NULL_BIND :
                    RPC_BUS_DRIVER_RELATIVE_MULTI_BIND_ERROR;
            throw new ResponseException(i18NCodeEnum);
        }

        return new KV<>(count, relatives.get(0));
    }

    /**
     * @param pointDistance 起时点的经纬度
     * @return KV , K:开始经纬度 ;V:结束经纬度
     * @author Anson
     * @date 17-3-30
     * @name 分割起时点的经纬度
     * @since 1.0.3
     */
    public static KV<Point, Point> convert(PointDistance pointDistance) {
        if (pointDistance == null) {
            return null;
        }
        KV<Point, Point> kv = new KV<Point, Point>(new CommonPoint(pointDistance.getStartX(), pointDistance.getStartY
                ()), new CommonPoint(pointDistance.getEndX(), pointDistance.getEndY()));
        return kv;
    }

    /**
     * @param driverId 司机id
     * @author Anson
     * @date 17-3-23
     * @name 验证并校验司机
     * @since 1.0.2
     */
    UserInfoBack validateAndGetUserInfo(String driverId) {
        UserCenterFacade userCenterFacade = this.getUserFacade();
        return userCenterFacade.validateAndGetUserInfo(driverId);
    }

    /**
     * @author Anson
     * @date 17-4-17
     * @name 获取用户facade
     * @since 1.0.4
     */
    UserCenterFacade getUserFacade() {
        return this.facade("usercenter", UserCenterFacade.class);
    }


}
